<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/2/26
 * Time: 15:30
 */
namespace App\Services;
use App\Models\VideoChatRoom;
use Illuminate\Support\Facades\DB;
use App\Models\User;
use App\Models\HxUsers;
use App\exption\hx_im\Hxim;
use App\Models\FailFriend;
use App\Models\UserDynamicList;

class VideoChatService
{
    private $_msg;
    private $_recipient_name;
    private $_user_info;
    private $_uid;

    /**
     * @desc 创建视频聊天房间号
     * @param $uid
     * @param $recipient_uid
     * @return array
     */
    public function video_chat($uid, $recipient_uid)
    {
        $this->_uid = $uid;
        if(!$this->_check_data($uid, $recipient_uid)) {
            return $this->_msg;
        }
        // 生成房间号
        $room_id = $uid.md5(uniqid(rand(), true)).$recipient_uid;
        $room_data = [
            'room_id' => $room_id,
            'uid' => $uid,
            'recipient_uid' => $recipient_uid,
            'created_at' => time(),
        ];

        // 检测双方是否同时发起视频聊天

        $rs = VideoChatRoom::insert($room_data);
        if(!$rs) {
            $this->_set_msg(10253, '视频聊天邀请出错');
            return false;
        }

        // 整合返回的数据
        $data = [
            'room_id' => $room_id,
            'recipient_username' => $this->_recipient_name,
            'sex' => $this->_user_info->sex,
            'avatar' => $this->_user_info->avatar ? getSignUrl($this->_user_info->avatar) : null,
            'is_online' => 1
        ];

        $this->_set_msg('0', '', $data);
        return $this->_msg;
    }

    /**
     * @desc 检测视频聊天的数据
     * @param $uid
     * @param $recipient_uid
     * @return bool
     */
    private function _check_data($uid, $recipient_uid) {
        if($recipient_uid == $uid) {
            $this->_set_msg(10254, '暂不能和自己视频聊天');
            return false;
        }

        // 检测黑名单
        if(!$this->_check_fail_friend($uid, $recipient_uid)) {
            $this->_set_msg(10255, '你当前正在对方的黑名单列表，暂不能发起视频聊天哦');
            return false;
        }

        $this->_user_info = User::where(['id' => $recipient_uid])->first(['sex', 'avatar']);
        if(!$this->_user_info) {
            $this->_set_msg(10005, '用户不存在');
            return false;
        }

        // 检测对方的通讯状态
        if(!$this->_check_communication_status($uid, $recipient_uid)) {
            $this->_set_msg(10256, '对方正在忙');
            return false;
        }

        // 检测我的环信状态
        if(!$this->_check_hx_users_status($uid)) {
            $this->_set_msg(10257, '连接出错');
            return false;
        }

        // 检测
        if(!$this->_check_hx_users_status($recipient_uid, true)) {
            $data = [
                'room_id' => null,
                'recipient_username' => $this->_recipient_name ?: null,
                'sex' => $this->_user_info->sex,
                'avatar' => $this->_user_info->avatar ? getSignUrl($this->_user_info->avatar) : null,
                'is_online' => 0,
            ];
            $this->_set_msg($this->_msg['code'], $this->_msg['msg'], $data);
            return false;
        }

        return true;
    }

    /**
     * @desc 检测黑名单
     * @param $uid
     * @param $recipient_uid
     * @return bool
     */
    private function _check_fail_friend($uid, $recipient_uid)
    {
        // 解除发起人拉黑邀请人
        $is_record = FailFriend::where(['uid' => $uid, 'friend_uid' => $recipient_uid, 'status' => 1])->first();
        if($is_record) {
            FailFriend::where(['id' => $is_record->id])->update(['status' => 2]);
        }

        // 检测接收人是否拉黑发起人
        if(FailFriend::where(['uid' => $recipient_uid, 'friend_uid' => $uid, 'status' => 1])->first()) {
            return false;
        }

        return true;
    }

    /**
     * @desc 检测用户的视频聊天状态
     * @param $uid  发起人ID
     * @param $recipient_uid 接收人ID
     * @return bool
     */
    private function _check_communication_status($uid, $recipient_uid)
    {
        $model = new VideoChatRoom();
        // 处理我发起的房间号异常退出
        $uid_record_list = VideoChatRoom::where(['uid' => $uid])->whereIn('status',[0,1])->get();
        if($uid_record_list) {
            foreach($uid_record_list as $uid_record) {
                VideoChatRoom::where(['id' => $uid_record->id])->update(['status' => 4, 'updated_at' => time(), 'remark' => '不正常退出视频聊天']);
            }
        }

        // 处理我的是被邀请的房间(处理场景：A发给B(A已获得房间号,但B还没有接通),B发给C)
        $recipient_uid_list = VideoChatRoom::where(['recipient_uid' => $uid])->whereIn('status',[0,1])->get();
        // 处理上一次通话状态的异常退出
        if($recipient_uid_list) {
            foreach($recipient_uid_list as $recipient_uid_record) {
                if($recipient_uid_record->created_at > (time() - 8)) {
                    continue;
                }
                VideoChatRoom::where(['id' => $recipient_uid_record->id])->update(['status' => 4, 'updated_at' => time(), 'remark' => '不正常退出视频聊天']);
            }
        }

        // 处理上一次通话状态的异常退出
        /*if($recipient_uid_record && $recipient_uid_record->created_at < (time() - 9)) {
            VideoChatRoom::where(['id' => $recipient_uid_record->id])->update(['status' => 4, 'updated_at' => time(), 'remark' => '不正常退出视频聊天']);
        }*/

        // 检测接收人的视频聊天状态
        $sql = "select id from " . $model->getTable() . " where (uid=? or recipient_uid=?) and status in(0, 1)";
        $recipient_record = DB::select($sql, [$recipient_uid, $recipient_uid]);
        if($recipient_record) {
            return false;
        }

        return true;
    }

    /**
     * @desc 检测环信的状态状态
     * @param $uid
     * @param bool $is_dynamic 是否写入动态
     * @return bool
     */
    private function _check_hx_users_status($uid, $is_dynamic=false)
    {
        $is_record = HxUsers::where(['uid' => $uid , 'hx_activated' => 1, 'status' => 1])->first();
        if(!$is_record) {
            $this->_set_msg('10257', '连接出错');
            return false;
        }
        $hx_username = $is_record->hx_username;
        $hx_im = new Hxim();
        if($is_dynamic) {
            $this->_recipient_name = $hx_username;
        }
        $get_hx_user_url = $hx_im->base_url.'/'.$hx_im->org_name.'/'.$hx_im->app_name.'/users/'.$hx_username.'/status';
        $hx_user_status = $hx_im->curl_get_json($get_hx_user_url);
        if($hx_im->http_code == 200){
            $hx_user_data = json_decode($hx_user_status, true);
            if($hx_user_data['data'][$hx_username] == 'online') {
                return true;
            }
        }

        // 接收人离线,写入动态
        if($is_dynamic) {
            $UserDynamicListModel = new UserDynamicList();
            $UserDynamicListModel->uid = $uid;
            $UserDynamicListModel->type = 4;
            $UserDynamicListModel->operation_id = 0;
            $UserDynamicListModel->parent_id = 0;
            $UserDynamicListModel->option_uid = $this->_uid;
            $UserDynamicListModel->media_id = 0;
            $UserDynamicListModel->option_other = '';
            $UserDynamicListModel->option_content = '发起了视频邀请';
            $UserDynamicListModel->create_time = time();
            $UserDynamicListModel->update_time = time();
            $UserDynamicListModel->status = 1;
            $UserDynamicListModel->save();
            $this->_set_msg(10258, '对方处于离线');
        }

        return false;
    }

    /**
     * @desc 修改视频聊天的状态
     * @param $uid
     * @param $room_id
     * @param $status
     * @param $duration_time
     * @return array
     */
    public static function modify_video_chat_status($uid, $room_id, $status, $duration_time)
    {
        if(!in_array($status, [1,2,3,4])) {
            return ['code' => 10128, 'msg' => '参数异常'];
        }

        $model = new VideoChatRoom();
        $sql = "select id,status from " . $model->getTable() . " where (uid=? or recipient_uid=?) and status in(0, 1) and room_id = '".$room_id."'";
        $is_record = DB::select($sql, [$uid, $uid]);
        if(!$is_record) {
            return ['code' => 0, 'msg' => 'ok'];
        }
        $room_info = array_pop($is_record);
        if($room_info->status == $status) {
            return ['code' => 0, 'msg' => 'ok'];
        }
        VideoChatRoom::where(['id' => $room_info->id])->update(['status' => $status, 'updated_at' => time(), 'duration_time' => $duration_time]);

        return ['code' => 0, 'msg' => 'ok'];
    }

    /**
     * @desc 设置信息
     * @param $code
     * @param $msg
     * @param $data
     * @return array
     */
    private function _set_msg($code, $msg, $data=[])
    {
        return $this->_msg = ['code' => $code, 'msg' => $msg, 'data' => $data];
    }
}